package org.finesys.common.database.config;

import com.baomidou.dynamic.datasource.creator.DataSourceCreator;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.creator.HikariDataSourceCreator;
import com.baomidou.dynamic.datasource.processor.DsHeaderProcessor;
import com.baomidou.dynamic.datasource.processor.DsProcessor;
import com.baomidou.dynamic.datasource.processor.DsSessionProcessor;
import com.baomidou.dynamic.datasource.processor.DsSpelExpressionProcessor;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import org.finesys.common.database.core.config.ClearTtlDataSourceFilter;
import org.finesys.common.database.core.config.DsLastParamProccessor;
import org.finesys.common.database.core.config.JdbcDynamicDataSourceProvider;
import org.finesys.common.database.core.properties.FineDataSourceProperties;
import org.jasypt.encryption.StringEncryptor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.expression.BeanFactoryResolver;

import java.util.ArrayList;
import java.util.List;

@AutoConfiguration
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(FineDataSourceProperties.class)
public class MyDynamicDataSourceAutoConfiguration {


    /**
     * 从数据库获取数据源信息
     */
    @Bean
    public DynamicDataSourceProvider dynamicDataSourceProvider(DefaultDataSourceCreator defaultDataSourceCreator, StringEncryptor stringEncryptor, FineDataSourceProperties dataSourceProperties) {
        return new JdbcDynamicDataSourceProvider(defaultDataSourceCreator, stringEncryptor, dataSourceProperties);
    }

    /**
     * 动态解析数据源
     */
    @Bean
    public DsProcessor dsProcessor(BeanFactory beanFactory) {
        DsLastParamProccessor dsLastParamProccessor = new DsLastParamProccessor();
        DsHeaderProcessor dsHeaderProcessor = new DsHeaderProcessor();
        DsSessionProcessor dsSessionProcessor = new DsSessionProcessor();
        DsSpelExpressionProcessor dsSpelExpressionProcessor = new DsSpelExpressionProcessor();
        dsSpelExpressionProcessor.setBeanResolver(new BeanFactoryResolver(beanFactory));
        dsLastParamProccessor.setNextProcessor(dsHeaderProcessor);
        dsHeaderProcessor.setNextProcessor(dsSessionProcessor);
        dsSessionProcessor.setNextProcessor(dsSpelExpressionProcessor);
        return dsLastParamProccessor;
    }

    /**
     * 默认数据源创建器
     *
     * @param hikariDataSourceCreator Hikari数据源创建器
     * @return 默认数据源创建器
     */
    @Bean
    public DefaultDataSourceCreator defaultDataSourceCreator(HikariDataSourceCreator hikariDataSourceCreator) {
        DefaultDataSourceCreator defaultDataSourceCreator = new DefaultDataSourceCreator();
        List<DataSourceCreator> creators = new ArrayList<>();
        creators.add(hikariDataSourceCreator);
        defaultDataSourceCreator.setCreators(creators);
        return defaultDataSourceCreator;
    }

    /**
     * 清除Ttl数据源过滤器
     *
     * @return 清除Ttl数据源过滤器
     */
    @Bean
    public ClearTtlDataSourceFilter clearTtlDsFilter() {
        return new ClearTtlDataSourceFilter();
    }
}
